﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Practices.Unity;
using Sahit.iSoilHotel.Infrastructure.DataAccess.MainBoundedContext.UnitOfWork;
using Sahit.iSoilHotel.Domain.MainBoundedContext.Tavern.Aggregates.AuthenticationAgg;
using Sahit.iSoilHotel.Infrastructure.DataAccess.MainBoundedContext.Tavern.Repositories;
using Sahit.iSoilHotel.Infrastructure.Crosscutting.Adapter;
using Sahit.iSoilHotel.Infrastructure.Crosscutting.NetFramework.Adapter;
using Sahit.iSoilHotel.Application.MainBoundedContext.Tavern.Interfaces;
using Sahit.iSoilHotel.Application.MainBoundedContext.Tavern.Services;
using Sahit.iSoilHotel.DistributedServices.MainBoundedContext.Interfaces;
using Sahit.iSoilHotel.Domain.MainBoundedContext.Tavern.Services;
using Sahit.iSoilHotel.Domain.MainBoundedContext.Tavern.Aggregates.RecordAgg;
using Sahit.iSoilHotel.Domain.MainBoundedContext.Tavern.Aggregates.CustomerAgg;
using Sahit.iSoilHotel.Domain.MainBoundedContext.Tavern.Aggregates.PriceAgg;
using Sahit.iSoilHotel.Domain.MainBoundedContext.Tavern.Aggregates.RoomAgg;

namespace Sahit.iSoilHotel.DistributedServices.MainBoundedContext.InstanceProviders
{
    public static class Container
    {
        #region Properties

        static IUnityContainer _currentContainer;

        /// <summary>
        /// Get the current configured container
        /// </summary>
        /// <returns>Configured container</returns>
        public static IUnityContainer Current
        {
            get
            {
                return _currentContainer;
            }
        }

        #endregion

        #region Constructor

        static Container()
        {
            ConfigureContainer();

            ConfigureFactories();
        }

        #endregion

        #region Methods

        static void ConfigureContainer()
        {
            /*
             * Add here the code configuration or the call to configure the container 
             * using the application configuration file
             */

            _currentContainer = new UnityContainer();


            //-> Unit of Work and repositories
            _currentContainer.RegisterType(typeof(MainBCUnitOfWork), new PerResolveLifetimeManager());

            _currentContainer.RegisterType<IAccountRepository, AccountRepository>();
            _currentContainer.RegisterType<IRecordRepository, RecordRepository>();
            _currentContainer.RegisterType<ICustomerRepository, CustomerRepository>();
            _currentContainer.RegisterType<IPriceCodeRepository, PriceCodeRepository>();
            _currentContainer.RegisterType<IPriceRepository, PriceRepository>();
            _currentContainer.RegisterType<IRoomRepository, RoomRepository>();
            _currentContainer.RegisterType<IRoomTypeRepository, RoomTypeRepository>();
            _currentContainer.RegisterType<IBuildingRepository, BuildingRepository>();

            //-> Adapters
            _currentContainer.RegisterType<ITypeAdapterFactory, AutomapperTypeAdapterFactory>(new ContainerControlledLifetimeManager());

            //-> Domain Services
            _currentContainer.RegisterType<IReserveService, ReserveService>();
            _currentContainer.RegisterType<ICheckInService, CheckInService>();
            _currentContainer.RegisterType<ICheckOutService, CheckOutService>();

            //-> Application services
            _currentContainer.RegisterType<IAccountService, AccountService>();
            _currentContainer.RegisterType<IRecordService, RecordService>();
            _currentContainer.RegisterType<ICustomerService, CustomerService>();
            _currentContainer.RegisterType<IPriceCodeService, PriceCodeService>();
            _currentContainer.RegisterType<IPriceService, PriceService>();
            _currentContainer.RegisterType<IRoomService, RoomService>();
            _currentContainer.RegisterType<IRoomTypeService, RoomTypeService>();

            //-> Distributed Services
            _currentContainer.RegisterType<ITavernAuthenticationService, TavernAuthenticationService>();
            _currentContainer.RegisterType<ITavernRecordService, TavernRecordService>();
            _currentContainer.RegisterType<ITavernRoomService, TavernRoomService>();
        }


        static void ConfigureFactories()
        {
            //LoggerFactory.SetCurrent(new TraceSourceLogFactory());
            //EntityValidatorFactory.SetCurrent(new DataAnnotationsEntityValidatorFactory());

            var typeAdapterFactory = _currentContainer.Resolve<ITypeAdapterFactory>();
            TypeAdapterFactory.SetCurrent(typeAdapterFactory);
        }

        #endregion
    }
}